package br.com.binding.rebind.generator;

import java.io.PrintWriter;

import br.com.binding.rebind.BoundModelClass;
import br.com.binding.rebind.template.Bound_ModelTemplate;

import com.google.gwt.core.ext.Generator;
import com.google.gwt.core.ext.GeneratorContext;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
import com.google.gwt.user.rebind.SourceWriter;

public class BoundModelGenerator extends Generator {

	private static final String SOURCES_PROPERTY_CHANGES = "br.com.binding.client.event.SourcesPropertyChanges";
	private static final String PROPERTY_CHANGE_SUPPORT = "br.com.binding.client.event.PropertyChangeSupport";
	private static final String PROPERTY_CHANGE_LISTENER = "br.com.binding.client.event.PropertyChangeListener";
	private static final String BOUND_PREFIX = "Bound_";

	public String generate(TreeLogger logger, GeneratorContext context,
			String typeName) throws UnableToCompleteException {
		
		TypeOracle oracle = context.getTypeOracle();
		JClassType type = oracle.findType(typeName);

		BoundModelClass modelClass = new BoundModelClass(type);
		String generatedClass = new Bound_ModelTemplate().generate(modelClass);
		System.out.println(generatedClass);
		
        String packageName = modelClass.getPackageName();
		String generatedClassName = BOUND_PREFIX+modelClass.getClassName();
		
		PrintWriter printer = context.tryCreate(logger, packageName, generatedClassName);

        if (printer == null){
			return null;
        } 
        
        ClassSourceFileComposerFactory composer = null;
        composer = new ClassSourceFileComposerFactory(packageName, generatedClassName);
        
        composer.setSuperclass(type.getSimpleSourceName());
        composer.addImplementedInterface(SOURCES_PROPERTY_CHANGES);
        composer.addImport(PROPERTY_CHANGE_LISTENER);
        composer.addImport(PROPERTY_CHANGE_SUPPORT);
        composer.addImport(SOURCES_PROPERTY_CHANGES);
        
        SourceWriter sourceWriter = composer.createSourceWriter(context, printer);
        sourceWriter.println(generatedClass);
        context.commit(logger, printer); 
		return packageName + "." + generatedClassName;
	}
}